package com.hp.bon.sgw.wh.channel.handler;

import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.hp.bon.sgw.Constants;
import com.hp.bon.sgw.bean.XmlMessage;
import com.hp.bon.sgw.core.BuzProcessorManager;
import com.hp.bon.sgw.core.CallParam;
import com.hp.bon.sgw.core.channel.SoapChannel;
import com.hp.bon.sgw.core.channel.handler.IAsynCallHandler;
import com.hp.bon.sgw.threads.TaskManager;
import com.hp.bon.sgw.wh.service.UserResourceConfigService;
import com.hp.bon.sgw.wh.util.DateUtil;
import com.hp.bon.sgw.wh.utils.LogUtil;
import com.hp.bon.sgw.wh.utils.ResultCodeUtil;
import com.hp.ocs.diameter.message.*;
import org.simpleframework.http.Request;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @ClassName: QryPaymentHandle
 * @Description: 3.2.12.1缴费销帐记录查询API
 */
public class QryPaymentHandle2 implements IAsynCallHandler {
	private static final Logger _log = LoggerFactory.getLogger(QryPaymentHandle2.class);

	private static final Object XmlMessage = null;
	private UserResourceConfigService userResourceConfigService ;
	private PrintStream printStream;
	private JSONObject requestObject;
	private int flag=0;//0 标识为旧流程
    private long startTime;
    private Request request;
	public QryPaymentHandle2(PrintStream printStream, JSONObject requestObject, Request request, long startTime) {
		this.printStream = printStream;
		this.requestObject = requestObject;
        this.startTime = startTime;
        this.request = request;
	}

	@Override
	public int getProtocolType() {
		return 0;
	}

	@Override
	public void onCallResult(CallParam callParam) {
		XmlMessage ack = null;
		Object response = null;
		if (callParam.getResponse() != null) {
			_log.warn("getResponse():");
			response = callParam.getResponse();
		} else if (callParam.getRecvResponse() != null) {
			_log.warn("getRecvResponse():");
			response = callParam.getRecvResponse();
		}
		if (response == null) {
			int _retcodeTmp = callParam.getRetCode() == 3002 ? 11202 : callParam.getRetCode();
			ack = SoapChannel.createERRAnwser(callParam.getSessionId(), _retcodeTmp, callParam.getResultMsg());
			callParam.setServiceResultCode(_retcodeTmp);// 11203
		} else {
			if (response instanceof Message) {// CCA -> XML
				ack = BuzProcessorManager.getInstance().convertMessageToAck(callParam);
			} else if (response instanceof XmlMessage) {
				ack = (XmlMessage) response;
			} else {
				_log.warn("unknown response type:" + callParam.getResponse().getClass().getName());
			}
		}
		try {
			
			if (response instanceof Message) {
                _log.info("================response instanceof Message");
            }else if (response instanceof XmlMessage) {
                _log.info("================response instanceof XmlMessage");
            }
			String respXML = convertResponseString(response, callParam.getServiceResultCode());

			byte[] resp = respXML.getBytes("UTF-8");
			ack.setLength(resp.length);
			ack.setMsgTime(System.currentTimeMillis());
			printStream.write(resp);
			printStream.close();
			callParam.setResponse(ack);
//			if (callParam.getRetCode() == Constants.ResultCode.SUCCESS) {// 成功的消息，请求应答入库
//				MessageDetail detail = new MessageDetail();
//				detail.setBusinessCallId(callParam.getBussinessCallId());
//				detail.setSessionId(callParam.getSessionId());
//				detail.setServiceContextId(callParam.getServiceContextId());
//				detail.setMessageType(MessageType.WSA);
//				detail.setDetails(ack.getDATA());
//				detail.setMsgTime(new Date(ack.getMsgTime()));
//				detail.setOpType("send");
//				detail.setHostId(callParam.getUserName());
//				MessageDetailCacheManager.getInstance().add(detail);
//			}
            //记录到日志
            LogUtil.saveLogToABM(request,respXML,startTime);
			TaskManager.taskProcess(callParam);
            _log.info("http response(cfq) " + respXML);

		} catch (UnsupportedEncodingException e) {
			_log.info("convertResponseString UnsupportedEncodingException error,msg=" + e.getMessage());
		} catch (IOException e) {
			_log.info("convertResponseString IOException,msg=" + e.getMessage());
		}catch (Exception e) {
			e.printStackTrace();
			_log.error("convertResponseString IOException,msg=" + e.getMessage());
		}
	}
	

	
	
	/**
	 * 返回最终json格式数据
	 * @param answer
	 * @param serviceResultCode
	 * @return
	 */
	@SuppressWarnings("unchecked")
	private String convertResponseString(Object answer, int serviceResultCode) {
        _log.info("QryPaymentHandle2 serviceResultCode = {}", serviceResultCode);
        String response = "";
        Map<String, Object> data = new HashMap<String, Object>();
        Map<String, Object> map = getAvpsFromMessage((Message)answer);//DCC返回结果
        if(map == null){
            // 解析下游返回数据出错
            data.put("resultCode", "-1");
            data.put("resultMsg", "查询失败");
        }else if(serviceResultCode != 0){
            // 如果返回了错误码，则将错误信息转给用户
            data.put("resultCode", serviceResultCode+"");
            data.put("resultMsg", "查询失败");
        }else{
            data.put("resultCode", "0");
            data.put("resultMsg", "销账缴费记录查询成功");
            List<Map<String, Object>> list = (List<Map<String, Object>>) map.get("list");
            List<Map<String, Object>> paymentInfoList=new ArrayList<Map<String, Object>>();
            if(list != null){
                for(Map<String, Object> tempMap : list){
                    Map<String,Object> newMap=new HashMap<String, Object>();
                    newMap.put("amount",tempMap.get("Payment_Amount"));
                    if(tempMap.get("StartTime") == null){
                        //2.0
                        newMap.put("paymentDate",tempMap.get("StateDate"));
                    }else{
                        //3.0
                        newMap.put("paymentDate",tempMap.get("StartTime"));
                    }
                    newMap.put("balance",0);
                    newMap.put("balanceTypeId",tempMap.get("BalanceTypeFlag"));
                    newMap.put("paymentId",Long.valueOf((String)tempMap.get("Req_Seria")));
                    newMap.put("paymentChannel",getPaymentChannel(tempMap.get("PayChannelId")));
                    newMap.put("accNbrDetail",tempMap.get("accnbrDetail"));
                    newMap.put("paymentMethod",tempMap.get("payment_method"));
                    paymentInfoList.add(newMap);
                }
            }
            data.put("paymentInfoList",paymentInfoList);
        }
        String newCode = ResultCodeUtil.updateResultCode(data.get("resultCode"), userResourceConfigService.getValue("api_resultCode"), userResourceConfigService.getValue("api_defaultResult"));
        data.put("resultCode", newCode);
        return new Gson().toJson(data);
	}

	
	/**
	 * 处理CCA结果
	 * @param answer
	 * @return
	 */
	public Map<String, Object> getAvpsFromMessage(Message answer) {
		Map<String, Object> map = new HashMap<String, Object>();
        List<Map<String, Object>> listMap=new ArrayList<Map<String, Object>>();
		try {
			AVP avp = answer.find(Constants.DIAMETER_AVP_SERVICE_INFOMATION, Constants.DIAMETER_VENDOR_3GPP);
			AVP_Grouped avpServiceInfomation = new AVP_Grouped(avp);
			AVP[] avps = avpServiceInfomation.queryAVPs();
			for (AVP avpData : avps) {
				if (avpData.code() == 20631 && avpData.vendorID() == Constants.DIAMETER_VENDOR_CT) {
					map.put("Result", String.valueOf(new AVP_Unsigned32(avpData).queryValue()));
				}
				
				if (avpData.code() == 80407 && avpData.vendorID() == Constants.DIAMETER_VENDOR_CT) {
					map.put("Para_Field_Result", new AVP_UTF8String(avpData).queryValue());
				}
				if (avpData.code() == 93057 && avpData.vendorID() == Constants.DIAMETER_VENDOR_CT) {
                    map.put("Payment_state", new AVP_UTF8String(avpData).queryValue());
				}

                if (avpData.code() == 20649 && avpData.vendorID() == Constants.DIAMETER_VENDOR_CT) {
                    Map<String, Object> infoMap = new HashMap<String, Object>();
                    AVP_Grouped avp_grouped = new AVP_Grouped(avpData);
                    AVP[] paymentAvps = avp_grouped.queryAVPs();
                    for (AVP info : paymentAvps) {
                        if (info.code() == 20635 && info.vendorID() == Constants.DIAMETER_VENDOR_CT) {
                            infoMap.put("Req_Seria", new AVP_UTF8String(info).queryValue());
                        }
                        if (info.code() == 80127 && info.vendorID() == Constants.DIAMETER_VENDOR_CT) {
                            infoMap.put("Payment_Amount", new AVP_Integer32(info).queryValue());
                        }
                        if (info.code() == 80129   && info.vendorID() == Constants.DIAMETER_VENDOR_CT) {
                            infoMap.put("payment_method", new AVP_Integer32(info).queryValue());
                        }
                        if (info.code() == 90214   && info.vendorID() == Constants.DIAMETER_VENDOR_CT) {
                            infoMap.put("PayChannelId", new AVP_Integer32(info).queryValue());
                        }
                        if (info.code() == 5073    && info.vendorID() == Constants.DIAMETER_VENDOR_CT) {
                            infoMap.put("StartTime",new AVP_UTF8String(info).queryValue() );
                        }
                        if (info.code() == 20655   && info.vendorID() == Constants.DIAMETER_VENDOR_CT) {
                            infoMap.put("Balance_Type",new AVP_Integer32(info).queryValue() );
                        }
                        if (info.code() == 90226  && info.vendorID() == Constants.DIAMETER_VENDOR_CT) {
                            infoMap.put("accnbrDetail", new AVP_UTF8String(info).queryValue() );
                        }
                        if (info.code() == 80411  && info.vendorID() == Constants.DIAMETER_VENDOR_CT) {
                            infoMap.put("Latn_Id",new AVP_UTF8String(info).queryValue() );
                        }
                        if (info.code() == 90208    && info.vendorID() == Constants.DIAMETER_VENDOR_CT) {
                            infoMap.put("BalanceTypeFlag", new AVP_Integer32(info).queryValue() );
                        }
                        if (info.code() == 80419    && info.vendorID() == Constants.DIAMETER_VENDOR_CT) {
                            infoMap.put("StateDate", new AVP_UTF8String(info).queryValue() );
                        }
                    }
                    listMap.add(infoMap);
                }

			}
            map.put("list",listMap);
        } catch (Exception e) {
			map = null;
			_log.info("getAvpsFromMessage Exception error,msg=" + e.getMessage());
		}
		return map;
	}

	private Object getPaymentDate(Object date){
	    //20200319134506
	    try{
	        return DateUtil.DateToStr(DateUtil.StrToDate(date.toString(),"yyyyMMddHHmmss"),"yyyy-MM-dd HH:mm:ss");
        }catch (Exception e){
            return date;
        }
    }


    /**
     * 处理paymentChannel 字段为空 ,并且转换为 Long类型
     * @return
     */
    private Object getPaymentChannel(Object paymentChannel){
        try {
            if(paymentChannel == null || "null".equals(paymentChannel)  || "".equals(paymentChannel)){
                //paymentChannel 为空
                return 7;
            }else{
                return Long.valueOf(paymentChannel.toString());
            }
        }catch (Exception e){
            return paymentChannel;
        }

    }


	public static void main(String[] args) {
//		String buildStringMes="\r\n" + 
//				"<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:web=\"http://webservice.asiainfo.com/\">\r\n" + 
//				"  <soapenv:Header/>\r\n" + 
//				"  <soapenv:Body>\r\n" + 
//				"    <web:qryPayment>\r\n" + 
//				"      <QryPaymentRequest>\r\n" + 
//				"        <billingCycleId>201909</billingCycleId>  \r\n" + 
//				"        <operAttrStruct>\r\n" + 
//				"          <staffId>1</staffId>\r\n" + 
//				"          <operOrgId>1</operOrgId>\r\n" + 
//				"          <operTime>20191106</operTime>\r\n" + 
//				"          <operPost>1</operPost>\r\n" + 
//				"          <operServiceId>1</operServiceId>\r\n" + 
//				"          <lanId>842011</lanId>\r\n" + 
//				"        </operAttrStruct>\r\n" + 
//				"        <svcObjectStruct> \r\n" + 
//				"          <objType>3</objType>\r\n" + 
//				"          <objValue>18972140850</objValue>\r\n" + 
//				"          <objAttr>2</objAttr>\r\n" + 
//				"          <dataArea>1</dataArea>\r\n" + 
//				"        </svcObjectStruct>\r\n" + 
//				"      </QryPaymentRequest>\r\n" + 
//				"    </web:qryPayment>\r\n" + 
//				"  </soapenv:Body>\r\n" + 
//				"</soapenv:Envelope>";
//		String resp = sendWebService(buildStringMes,"http://133.0.209.70:7100/bossws/soap/billing?wsdl");
//		XStream xstream2 = new XStream(new DomDriver());
//		xstream2.alias("QryPaymentResponse", QryPaymentResponse.class);
//		
//		xstream2.alias("paymentInfoList", QryPaymentResponse.PaymentInfoList.class);
//		xstream2.addImplicitCollection( QryPaymentResponse.class, "paymentInfoList");//隐式集合 隐藏
//		
//		xstream2.alias("accNbrDetailList", QryPaymentResponse.PaymentInfoList.AccNbrDetail.class);
//		xstream2.addImplicitCollection( QryPaymentResponse.PaymentInfoList.class, "accNbrDetailList");//隐式集合 隐藏
//		xstream2.autodetectAnnotations(true);
//		//resp = getRespString(resp);
//		QryPaymentResponse qryPaymentResponse = null;
//		qryPaymentResponse = (QryPaymentResponse) xstream2.fromXML(resp.substring(resp.indexOf("<QryPaymentResponse"), resp.indexOf("</ns1:qryPaymentResponse>")));
//		System.out.println(qryPaymentResponse.getResultCode());
	}
	
}
